<script setup lang="ts">
/*
 * Color Consistency Improvements for Cross-Device Compatibility
 * 跨设备兼容性的颜色一致性改进
 * 
 * This component includes several improvements to ensure consistent color rendering
 * across different devices, graphics cards, and display settings:
 * 此组件包含多项改进以确保在不同设备、显卡和显示设置间保持一致的颜色渲染：
 * 
 * 1. Standardized Window/Level Values (VOI Range)
 *    标准化的窗宽窗位值（VOI范围）
 *    - Sets consistent CT window levels (-1000 to 1000) for all viewports
 *    - 为所有视口设置一致的CT窗宽窗位值（-1000到1000）
 * 
 * 2. Linear Interpolation Enforcement
 *    强制使用线性插值
 *    - Ensures consistent image interpolation across devices
 *    - 确保跨设备的一致图像插值
 * 
 * 3. CSS Color Profile Standardization
 *    CSS颜色配置文件标准化
 *    - Forces sRGB color space for consistent color interpretation
 *    - 强制使用sRGB色彩空间以获得一致的颜色解释
 * 
 * 4. Hardware Acceleration Optimization
 *    硬件加速优化
 *    - Uses GPU acceleration for consistent rendering performance
 *    - 使用GPU加速以获得一致的渲染性能
 * 
 * If colors still appear different on some devices, consider:
 * 如果某些设备上的颜色仍然不同，请考虑：
 * - Check monitor calibration and color profile settings
 * - 检查显示器校准和颜色配置文件设置
 * - Verify graphics driver updates
 * - 验证显卡驱动程序更新
 * - Consider browser color management settings
 * - 考虑浏览器颜色管理设置
 */

import { ref, onMounted, onUnmounted, nextTick } from 'vue'
import type { Types } from '@cornerstonejs/core'
import { 
  init as csRenderInit,
  RenderingEngine,
  Enums as csEnums,
  setVolumesForViewports,
  volumeLoader,
  cache,
  getRenderingEngine
} from '@cornerstonejs/core'
import { 
  init as csToolsInit,
  ToolGroupManager,
  CrosshairsTool,
  WindowLevelTool,
  PanTool,
  ZoomTool,
  StackScrollTool,
  Enums as ToolEnums,
  addTool,
  synchronizers
} from '@cornerstonejs/tools'
import { 
  init as dicomImageLoaderInit
} from '@cornerstonejs/dicom-image-loader'

// Refs for viewport elements
// 视口元素的引用
const axialRef = ref<HTMLDivElement>()       // 轴向视图引用
const sagittalRef = ref<HTMLDivElement>()    // 矢状视图引用
const coronalRef = ref<HTMLDivElement>()     // 冠状视图引用

// State
// 状态变量
const loading = ref(false)                   // 加载状态
const error = ref('')                        // 错误信息
const running = ref(false)                   // 运行状态
const selectedBlendMode = ref('Maximum Intensity Projection') // 选中的混合模式
const isInitialized = ref(false)             // 初始化状态

// Constants
// 常量定义
const volumeName = 'CT_VOLUME_ID'            // 体积名称
const volumeLoaderScheme = 'cornerstoneStreamingImageVolume' // 体积加载器方案
const volumeId = `${volumeLoaderScheme}:${volumeName}`       // 体积ID
const renderingEngineId = 'crosshairs-rendering-engine'      // 渲染引擎ID
const toolGroupId = 'crosshairs-tool-group'                  // 工具组ID
const viewportId1 = 'axial'                  // 轴向视图ID
const viewportId2 = 'sagittal'               // 矢状视图ID
const viewportId3 = 'coronal'                // 冠状视图ID
const viewportIds = [viewportId1, viewportId2, viewportId3]  // 视图ID数组
const synchronizerId = 'SLAB_THICKNESS_SYNCHRONIZER_ID'      // 同步器ID

// Viewport colors for reference lines
// 参考线颜色配置
const viewportColors: Record<string, string> = {
  [viewportId1]: 'rgb(200, 0, 0)',           // 轴向视图红色
  [viewportId2]: 'rgb(200, 200, 0)',         // 矢状视图黄色
  [viewportId3]: 'rgb(0, 200, 0)',           // 冠状视图绿色
}

// Viewport configuration arrays
// 视口配置数组
const viewportReferenceLineControllable = [viewportId1, viewportId2, viewportId3]  // 可控制参考线的视口
const viewportReferenceLineDraggableRotatable = [viewportId1, viewportId2, viewportId3]  // 可拖动和旋转参考线的视口
const viewportReferenceLineSlabThicknessControlsOn = [viewportId1, viewportId2, viewportId3]  // 启用切片厚度控制的视口

// Cornerstone instances
// Cornerstone实例
let renderingEngine: RenderingEngine | null = null  // 渲染引擎实例
let toolGroup: any = null                           // 工具组实例
let synchronizer: any = null                        // 同步器实例

// Create image IDs
// 创建图像ID列表
function createImageIds(): string[] {
  const imageIds: string[] = []
  
  // 生成DICOM图像ID列表
  for (let i = 0; i <= 55; i++) {
    const imageId = `wadouri:./buyaodicom/1.2.156.112605.66988329176330.240112035017.3.8924.51332_${i}.dcm`
    imageIds.push(imageId)
  }
  
  return imageIds
}

// Reference line configuration functions
// 参考线配置函数

// 获取参考线颜色
function getReferenceLineColor(viewportId: string) {
  return viewportColors[viewportId]
}

// 判断参考线是否可控
function getReferenceLineControllable(viewportId: string) {
  return viewportReferenceLineControllable.indexOf(viewportId) !== -1
}

// 判断参考线是否可拖动和旋转
function getReferenceLineDraggableRotatable(viewportId: string) {
  return viewportReferenceLineDraggableRotatable.indexOf(viewportId) !== -1
}

// 判断参考线是否启用切片厚度控制
function getReferenceLineSlabThicknessControlsOn(viewportId: string) {
  return viewportReferenceLineSlabThicknessControlsOn.indexOf(viewportId) !== -1
}

// Set up synchronizers
// 设置同步器
function setUpSynchronizers() {
  const { createSlabThicknessSynchronizer } = synchronizers
  synchronizer = createSlabThicknessSynchronizer(synchronizerId)

  // Add viewports to synchronizer
  // 将视口添加到同步器
  viewportIds.forEach((viewportId) => {
    synchronizer.add({
      renderingEngineId,
      viewportId,
    })
  })
  
  // Start with synchronizer disabled
  // 默认禁用同步器
  synchronizer.setEnabled(false)
}

// Update blend mode
// 更新混合模式
function updateBlendMode(mode: string) {
  let blendModeToUse: any
  
  // 根据选择设置对应的混合模式
  switch (mode) {
    case 'Maximum Intensity Projection':
      blendModeToUse = csEnums.BlendModes.MAXIMUM_INTENSITY_BLEND
      break
    case 'Minimum Intensity Projection':
      blendModeToUse = csEnums.BlendModes.MINIMUM_INTENSITY_BLEND
      break
    case 'Average Intensity Projection':
      blendModeToUse = csEnums.BlendModes.AVERAGE_INTENSITY_BLEND
      break
    default:
      blendModeToUse = csEnums.BlendModes.MAXIMUM_INTENSITY_BLEND
  }

  if (!toolGroup) return
  
  // 更新十字线工具的配置
  const crosshairsInstance = toolGroup.getToolInstance(CrosshairsTool.toolName)
  const oldConfiguration = crosshairsInstance.configuration
  
  crosshairsInstance.configuration = {
    ...oldConfiguration,
    slabThicknessBlendMode: blendModeToUse,
  }
  
  // Update the blendMode for actors to instantly reflect the change
  // 更新所有视口的混合模式以立即反映变化
  viewportIds.forEach((viewportId) => {
    const renderingEngine = getRenderingEngine(renderingEngineId)
    if (!renderingEngine) return
    
    const viewport = renderingEngine.getViewport(viewportId) as Types.IVolumeViewport
    viewport.setBlendMode(blendModeToUse)
    
    // Force consistent color rendering options
    // 强制使用一致的颜色渲染选项
    viewport.setProperties({
      // Ensure consistent interpolation and rendering
      // 确保一致的插值和渲染
      interpolationType: csEnums.InterpolationType.LINEAR
    })
    
    viewport.render()
  })
}

// Reset camera
// 重置相机视角
function resetCamera() {
  if (!renderingEngine) return
  
  // 重置轴向视图的相机
  const viewport = renderingEngine.getViewport(viewportId1) as Types.IVolumeViewport
  viewport.resetCamera({
    resetPan: true,       // 重置平移
    resetZoom: true,      // 重置缩放
    resetToCenter: true,  // 重置到中心
    resetRotation: true,  // 重置旋转
  })
  
  viewport.render()
}

// Main setup function
// 主设置函数
const setup = async () => {
  if (running.value) return
  
  running.value = true
  loading.value = true
  error.value = ''

  try {
    console.log('初始化 Cornerstone3D...')
    
    // Initialize Cornerstone
    // 初始化Cornerstone
    await csRenderInit()
    await csToolsInit()
    
    // Initialize DICOM Image Loader
    // 初始化DICOM图像加载器
    dicomImageLoaderInit({
      maxWebWorkers: 1,
      strict: false
    })
    
    // Register tools
    // 注册工具
    addTool(CrosshairsTool)    // 十字线工具
    addTool(WindowLevelTool)   // 窗宽窗位工具
    addTool(PanTool)           // 平移工具
    addTool(ZoomTool)          // 缩放工具
    addTool(StackScrollTool)   // 堆栈滚动工具
    
    console.log('工具注册成功')
    
    // Wait longer for DOM elements to be ready and properly sized
    // 增加等待时间，确保DOM元素完全渲染
    await new Promise(resolve => setTimeout(resolve, 1000))
    
    // Check viewport elements
    // 检查视口元素
    if (!axialRef.value || !sagittalRef.value || !coronalRef.value) {
      throw new Error('未找到视口元素')
    }
    
    // 确保视口元素有明确的尺寸
    if (axialRef.value) {
      axialRef.value.style.width = '100%'
      axialRef.value.style.height = '400px'
      axialRef.value.style.display = 'block'
    }
    
    if (sagittalRef.value) {
      sagittalRef.value.style.width = '100%'
      sagittalRef.value.style.height = '400px'
      sagittalRef.value.style.display = 'block'
    }
    
    if (coronalRef.value) {
      coronalRef.value.style.width = '100%'
      coronalRef.value.style.height = '400px'
      coronalRef.value.style.display = 'block'
    }
    
    // Force layout recalculation
    // 强制浏览器重新计算布局
    axialRef.value.offsetHeight
    sagittalRef.value.offsetHeight
    coronalRef.value.offsetHeight
    
    // 再次等待以确保样式应用
    await new Promise(resolve => setTimeout(resolve, 100))
    
    // Check viewport dimensions
    // 检查视口尺寸
    const axialRect = axialRef.value.getBoundingClientRect()
    const sagittalRect = sagittalRef.value.getBoundingClientRect()
    const coronalRect = coronalRef.value.getBoundingClientRect()
    
    console.log('视口尺寸:', {
      axial: `${axialRect.width}x${axialRect.height}`,
      sagittal: `${sagittalRect.width}x${sagittalRect.height}`,
      coronal: `${coronalRect.width}x${coronalRect.height}`
    })
    
    if (axialRect.width === 0 || sagittalRect.width === 0 || coronalRect.width === 0 ||
        axialRect.height === 0 || sagittalRect.height === 0 || coronalRect.height === 0) {
      throw new Error(`视口元素尺寸为零`)
    }
    
    // Clean up existing rendering engine if exists
    // 如果存在旧的渲染引擎，则先清理
    if (renderingEngine) {
      renderingEngine.destroy()
      renderingEngine = null
    }
    
    // Clean up existing tool group if exists
    // 如果存在旧的工具组，则先清理
    const existingToolGroup = ToolGroupManager.getToolGroup(toolGroupId)
    if (existingToolGroup) {
      ToolGroupManager.destroyToolGroup(toolGroupId)
    }
    
    // Create rendering engine
    // 创建渲染引擎
    renderingEngine = new RenderingEngine(renderingEngineId)
    
    // Define viewports
    // 定义视口配置
    const viewportInputArray = [
      {
        viewportId: viewportId1,
        type: csEnums.ViewportType.ORTHOGRAPHIC,
        element: axialRef.value,
        defaultOptions: {
          orientation: csEnums.OrientationAxis.AXIAL,
          background: [0, 0, 0] as Types.Point3
        },
      },
      {
        viewportId: viewportId2,
        type: csEnums.ViewportType.ORTHOGRAPHIC,
        element: sagittalRef.value,
        defaultOptions: {
          orientation: csEnums.OrientationAxis.SAGITTAL,
          background: [0, 0, 0] as Types.Point3
        },
      },
      {
        viewportId: viewportId3,
        type: csEnums.ViewportType.ORTHOGRAPHIC,
        element: coronalRef.value,
        defaultOptions: {
          orientation: csEnums.OrientationAxis.CORONAL,
          background: [0, 0, 0] as Types.Point3
        },
      },
    ]
    
    // Set viewports on rendering engine
    // 在渲染引擎上设置视口配置
    renderingEngine.setViewports(viewportInputArray)
    
    console.log('视口创建成功')
    
    // Create and load volume
    // 创建并加载体积数据
    const imageIds = createImageIds()
    console.log('加载体积数据，共', imageIds.length, '张图像')
    
    // Remove existing volume if it exists
    // 如果已存在相同ID的体积数据，则先移除它
    const existingVolume = cache.getVolume(volumeId)
    if (existingVolume) {
      cache.removeVolumeLoadObject(volumeId)
    }
    
    // Define volume
    // 定义体积数据并将其缓存
    const volume = await volumeLoader.createAndCacheVolume(volumeId, {
      imageIds,
    })
    
    // Load the volume first
    // 首先加载体积数据
    await volume.load()
    
    console.log('体积数据加载成功')
    
    // Set volumes for viewports
    // 为所有视口设置体积数据
    await setVolumesForViewports(
      renderingEngine,
      [{ volumeId }],
      viewportIds
    )
    
    // Set consistent window level values for all viewports
    // 为所有视口设置一致的窗宽窗位值
    if (renderingEngine) {
      viewportIds.forEach((viewportId) => {
        const viewport = renderingEngine!.getViewport(viewportId) as Types.IVolumeViewport
        // Set consistent window level values to ensure color consistency
        // 设置一致的窗宽窗位值以确保颜色一致性
        viewport.setProperties({
          voiRange: {
            lower: -1000,  // Standard CT window level for soft tissue
            upper: 1000    // 标准CT软组织窗宽窗位
          }
        })
      })
    }
    
    // Create tool group
    // 创建工具组，用于管理多个视口上的交互工具
    toolGroup = ToolGroupManager.createToolGroup(toolGroupId)
    
    // Add viewports to tool group FIRST
    // 首先将视口添加到工具组中
    viewportIds.forEach((viewportId) => {
      toolGroup.addViewport(viewportId, renderingEngineId)
    })
    
    // Add tools to tool group
    // 向工具组添加各种交互工具
    toolGroup.addTool(CrosshairsTool.toolName, {
      getReferenceLineColor,        // 获取参考线颜色的函数
      getReferenceLineControllable, // 确定参考线是否可控的函数
      getReferenceLineDraggableRotatable, // 确定参考线是否可拖动和旋转的函数
      getReferenceLineSlabThicknessControlsOn, // 确定参考线是否显示厚度控制的函数
      mobile: {
        enabled: window.matchMedia('(any-pointer:coarse)').matches, // 检测是否为移动设备
        opacity: 0.8,    // 移动设备上的不透明度
        handleRadius: 9, // 移动设备上的手柄半径
      }
    })
    toolGroup.addTool(WindowLevelTool.toolName)  // 添加窗宽窗位调整工具
    toolGroup.addTool(PanTool.toolName)          // 添加平移工具
    toolGroup.addTool(ZoomTool.toolName)         // 添加缩放工具
    toolGroup.addTool(StackScrollTool.toolName)  // 添加堆栈滚动工具
    
    // Set tool modes
    // 设置工具的激活模式和鼠标绑定
    toolGroup.setToolActive(CrosshairsTool.toolName, {
      bindings: [{ mouseButton: ToolEnums.MouseBindings.Primary }], // 主鼠标按钮(左键)激活十字线工具
    })
    toolGroup.setToolActive(WindowLevelTool.toolName, {
      bindings: [{ mouseButton: ToolEnums.MouseBindings.Primary, modifierKey: ToolEnums.KeyboardBindings.Shift }], // Shift+左键激活窗宽窗位工具
    })
    toolGroup.setToolActive(PanTool.toolName, {
      bindings: [{ mouseButton: ToolEnums.MouseBindings.Auxiliary }], // 中键激活平移工具
    })
    toolGroup.setToolActive(ZoomTool.toolName, {
      bindings: [{ mouseButton: ToolEnums.MouseBindings.Secondary }], // 右键激活缩放工具
    })
    toolGroup.setToolActive(StackScrollTool.toolName) // 激活堆栈滚动工具(无特定按键绑定)
    
    console.log('工具组配置成功')
    
    // Set up synchronizers
    // 设置同步器，用于在视口间同步操作
    setUpSynchronizers()
    
    // Apply initial blend mode
    // 应用初始的混合模式
    updateBlendMode(selectedBlendMode.value)
    
    // Render all viewports
    // 渲染所有视口
    renderingEngine.renderViewports(viewportIds)
    
    console.log('视口渲染成功')
    
    loading.value = false
    
  } catch (err: any) {
    console.error('设置错误:', err)
    error.value = err.message || '初始化查看器失败'
    loading.value = false
    running.value = false
  }
}

// Cleanup function
// 清理函数，用于销毁渲染引擎、工具组和同步器等资源
const cleanup = () => {
  if (renderingEngine) {
    renderingEngine.destroy()
    renderingEngine = null
  }
  
  if (toolGroup) {
    ToolGroupManager.destroyToolGroup(toolGroup.id)
    toolGroup = null
  }
  
  if (synchronizer) {
    synchronizer.destroy()
    synchronizer = null
  }
  
  cache.purgeCache() // 清除缓存中的所有数据
  running.value = false
}

// Toggle synchronizer
// 切换同步器的启用状态
function toggleSynchronizer(enabled: boolean) {
  if (synchronizer) {
    synchronizer.setEnabled(enabled)
  }
}

// Lifecycle
// 组件挂载后的生命周期钩子
onMounted(async () => {
  // 增加更长的等待时间，确保DOM完全渲染
  // 等待1秒，确保DOM元素完全渲染
  await new Promise(resolve => setTimeout(resolve, 1000))
  
  // 确保视口容器在DOM中可见
  // 检查视口元素是否都存在于DOM中
  if (axialRef.value && sagittalRef.value && coronalRef.value) {
    const container = document.querySelector('.viewport-grid')
    if (container) {
      // 确保容器可见
      // 强制设置容器为网格显示
      container.setAttribute('style', 'display: grid !important')
    }
    
    // 确保视口元素可见并有尺寸
    // 为所有视口元素设置明确的尺寸和显示属性
    ;[axialRef.value, sagittalRef.value, coronalRef.value].forEach(el => {
      el.style.width = '100%'
      el.style.height = '280px' // 与CSS中的高度保持一致
      el.style.display = 'block'
    })
    
    // 强制浏览器重新计算布局
    // 通过访问offsetHeight属性强制浏览器重新计算布局
    axialRef.value.offsetHeight
    
    // 再次等待以确保样式应用
    // 等待0.5秒，确保样式已被应用
    await new Promise(resolve => setTimeout(resolve, 500))
  }
  
  // 启动cornerstone设置
  // 初始化Cornerstone3D和相关组件
  setup()
})

// 组件卸载时的生命周期钩子，清理资源
onUnmounted(() => {
  cleanup()
})
</script>

<template>
  <div class="crosshairs-container">
    <!-- Header -->
    <!-- 页面头部，包含标题和状态信息 -->
    <div class="header">
      <h1><i class="icon">🔬</i> DICOM 三维切片查看器</h1>
      <div class="status" :class="{ loading: loading, error: !!error }">
        <span v-if="loading">⏳ 加载中...</span>
        <span v-else-if="error">❌ {{ error }}</span>
        <span v-else>✅ 就绪</span>
      </div>
    </div>
    
    <!-- Controls Toolbar -->
    <!-- 控制工具栏，包含混合模式选择、相机重置和同步厚度控制 -->
    <div class="toolbar" v-show="!loading && !error">
      <div class="tool-group">
        <label for="blend-mode">混合模式:</label>
        <select 
          id="blend-mode" 
          v-model="selectedBlendMode" 
          @change="updateBlendMode(selectedBlendMode)"
        >
          <option value="Maximum Intensity Projection">最大强度投影</option>
          <option value="Minimum Intensity Projection">最小强度投影</option>
          <option value="Average Intensity Projection">平均强度投影</option>
        </select>
      </div>
      
      <div class="tool-group">
        <button @click="resetCamera" class="tool-btn">重置视角</button>
      </div>
      
      <div class="tool-group">
        <label class="toggle">
          <input type="checkbox" @change="(e) => toggleSynchronizer((e.target as HTMLInputElement).checked)">
          <span class="toggle-label">同步切片厚度</span>
        </label>
      </div>
    </div>
    
    <!-- Viewport Grid - 注意这里不使用v-show，而是让容器始终存在 -->
    <!-- 视口网格，包含三个正交视图：轴向、矢状面和冠状面 -->
    <div class="viewport-grid">
      <div class="viewport-container">
        <div class="viewport-header">
          <span class="viewport-label">轴向视图</span>
        </div>
        <div ref="axialRef" class="viewport" id="axial"></div>
      </div>
      
      <div class="viewport-container">
        <div class="viewport-header">
          <span class="viewport-label">矢状视图</span>
        </div>
        <div ref="sagittalRef" class="viewport" id="sagittal"></div>
      </div>
      
      <div class="viewport-container">
        <div class="viewport-header">
          <span class="viewport-label">冠状视图</span>
        </div>
        <div ref="coronalRef" class="viewport" id="coronal"></div>
      </div>
    </div>

    <!-- Controls Instructions -->
    <!-- 控制说明，显示如何操作视口的指南 -->
    <div class="controls" v-show="!loading && !error">
      <div class="control-group">
        <strong>🖱️ 基本控制:</strong> 点击/拖动任意位置移动十字线 | 右键拖动 = 缩放 | 中键拖动 = 调整窗宽窗位
      </div>
      <div class="control-group">
        <strong>⚙️ 高级控制:</strong> 悬停在线上查找: 方形手柄(靠近中心) = 改变切片厚度 | 圆形手柄(远离中心) = 旋转轴线
      </div>
    </div>

    <!-- Loading/Error States -->
    <!-- 加载和错误状态显示 -->
    <div v-if="loading" class="loading-state">
      <div class="spinner"></div>
      <p>正在加载DICOM图像...</p>
    </div>
    
    <div v-if="error" class="error-state">
      <p>{{ error }}</p>
      <button @click="setup" class="retry-btn">重试</button>
    </div>
  </div>
</template>

<style scoped>
.crosshairs-container {
  padding: 2px;
  min-height: 100vh;
  background: #c0c0c0; /* Windows 95 经典背景色 */
  font-family: 'SimSun', 'MS Sans Serif', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  color: #000;
}

.header {
  text-align: center;
  margin-bottom: 4px;
  background: #000080; /* Windows 95 标题栏蓝色 */
  padding: 4px;
  border: 2px solid;
  border-color: #dfdfdf #808080 #808080 #dfdfdf;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header h1 {
  margin: 0;
  color: #fff;
  font-size: 16px;
  font-weight: bold;
  display: flex;
  align-items: center;
  gap: 8px;
}

.icon {
  font-size: 16px;
}

.status {
  font-size: 12px;
  font-weight: normal;
  padding: 2px 6px;
  border: 1px solid;
  border-color: #808080 #ffffff #ffffff #808080;
  background: #c0c0c0;
  color: #000;
}

.status.loading {
  background: #c0c0c0;
  color: #000;
}

.status.error {
  background: #c0c0c0;
  color: #f00;
}

.toolbar {
  display: flex;
  justify-content: flex-start;
  gap: 4px;
  background: #c0c0c0;
  border: 2px solid;
  border-color: #dfdfdf #808080 #808080 #dfdfdf;
  padding: 4px;
  margin-bottom: 4px;
  flex-wrap: wrap;
}

.tool-group {
  display: flex;
  align-items: center;
  gap: 4px;
}

select {
  padding: 1px 2px;
  border: 2px solid;
  border-color: #808080 #dfdfdf #dfdfdf #808080;
  background: #c0c0c0;
  font-size: 12px;
  font-family: 'SimSun', 'MS Sans Serif', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

.tool-btn {
  padding: 2px 6px;
  border: 2px solid;
  border-color: #dfdfdf #808080 #808080 #dfdfdf;
  background: #c0c0c0;
  color: #000;
  cursor: pointer;
  font-size: 12px;
  font-family: 'SimSun', 'MS Sans Serif', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

.tool-btn:active {
  border-color: #808080 #dfdfdf #dfdfdf #808080;
}

.toggle {
  display: flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
}

.toggle input {
  margin: 0;
}

.viewport-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
  margin-bottom: 4px;
}

.viewport-container {
  background: #c0c0c0;
  border: 2px solid;
  border-color: #dfdfdf #808080 #808080 #dfdfdf;
  padding: 2px;
}

.viewport-header {
  display: flex;
  justify-content: center;
  margin-bottom: 2px;
  background: #000080; /* Windows 95 标题栏蓝色 */
  color: #fff;
  padding: 2px 0;
}

.viewport-label {
  font-weight: bold;
  font-size: 12px;
}

.viewport {
  width: 100% !important;
  height: 280px !important; /* 减小高度使布局更紧凑 */
  min-height: 280px;
  background: #000;
  position: relative;
  overflow: hidden;
  display: block;
  border: 1px solid #808080;
  box-shadow: inset 1px 1px 2px #000;
  /* Add color consistency properties for cross-device compatibility */
  /* 添加颜色一致性属性以确保跨设备兼容性 */
  color-profile: sRGB;
  color-scheme: normal;
  -webkit-color-correction: sRGB;
  image-rendering: -webkit-optimize-contrast;
  image-rendering: crisp-edges;
  /* Force hardware acceleration for consistent rendering */
  /* 强制硬件加速以获得一致的渲染效果 */
  transform: translateZ(0);
  will-change: transform;
}

.controls {
  background: #c0c0c0;
  border: 2px solid;
  border-color: #dfdfdf #808080 #808080 #dfdfdf;
  padding: 6px;
  text-align: left;
  font-size: 12px;
  margin-bottom: 4px;
}

.control-group {
  margin-bottom: 4px;
  color: #000;
  font-size: 12px;
  border-left: 4px solid #000080;
  padding-left: 4px;
}

.control-group:last-child {
  margin-bottom: 0;
}

.loading-state, .error-state {
  text-align: center;
  padding: 10px;
  background: #c0c0c0;
  border: 2px solid;
  border-color: #dfdfdf #808080 #808080 #dfdfdf;
}

.spinner {
  width: 24px;
  height: 24px;
  border: 3px solid #808080;
  border-top: 3px solid #000080;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin: 0 auto 8px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.retry-btn {
  background: #c0c0c0;
  color: #000;
  border: 2px solid;
  border-color: #dfdfdf #808080 #808080 #dfdfdf;
  padding: 2px 8px;
  cursor: pointer;
  font-size: 12px;
  font-family: 'SimSun', 'MS Sans Serif', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  margin-top: 6px;
}

.retry-btn:active {
  border-color: #808080 #dfdfdf #dfdfdf #808080;
}

/* 添加Windows 95风格的滚动条 */
::-webkit-scrollbar {
  width: 16px;
  height: 16px;
}

::-webkit-scrollbar-track {
  background: #c0c0c0;
}

::-webkit-scrollbar-thumb {
  background: #c0c0c0;
  border: 2px solid;
  border-color: #dfdfdf #808080 #808080 #dfdfdf;
}

::-webkit-scrollbar-button {
  background: #c0c0c0;
  border: 2px solid;
  border-color: #dfdfdf #808080 #808080 #dfdfdf;
  display: block;
  height: 16px;
  width: 16px;
}

::-webkit-scrollbar-button:active {
  border-color: #808080 #dfdfdf #dfdfdf #808080;
}

@media (max-width: 1200px) {
  .viewport-grid {
    grid-template-columns: 1fr 1fr; /* 在中等屏幕上改为2列 */
  }
  
  .viewport {
    height: 220px;
  }
}

@media (max-width: 768px) {
  .viewport-grid {
    grid-template-columns: 1fr; /* 在小屏幕上改为1列 */
  }
  
  .viewport {
    height: 180px;
  }
}
</style>
